package cn.edu.sgu.www.mhxysy.service.fabao.impl;

import cn.edu.sgu.www.mhxysy.consts.CustomMessages;
import cn.edu.sgu.www.mhxysy.dto.fabao.FabaoDTO;
import cn.edu.sgu.www.mhxysy.entity.fabao.Fabao;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import cn.edu.sgu.www.mhxysy.function.computer.score.impl.FabaoScoreComputer;
import cn.edu.sgu.www.mhxysy.mapper.fabao.FabaoMapper;
import cn.edu.sgu.www.mhxysy.pager.Pager;
import cn.edu.sgu.www.mhxysy.pager.fabao.FabaoPager;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.service.fabao.FabaoService;
import cn.edu.sgu.www.mhxysy.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Service
public class FabaoServiceImpl implements FabaoService {

	private final FabaoMapper fabaoMapper;
	private final FabaoScoreComputer fabaoScoreComputer;

	@Autowired
	public FabaoServiceImpl(
			FabaoMapper fabaoMapper,
			FabaoScoreComputer fabaoScoreComputer) {
		this.fabaoMapper = fabaoMapper;
		this.fabaoScoreComputer = fabaoScoreComputer;
	}

	@Override
	public void compute(String fabaoId) {
		UpdateWrapper<Fabao> updateWrapper = new UpdateWrapper<>();

		updateWrapper.eq("id", fabaoId);
		updateWrapper.set("score", fabaoScoreComputer.compute(fabaoId));

		fabaoMapper.update(updateWrapper.getEntity(), updateWrapper);
	}

	@Override
	public void insert(FabaoDTO fabaoDTO) {
		fabaoDTO.setId(null);

		boolean result = validataDuplicate(fabaoDTO);

		if (result) {
			Fabao fabao = toEntity(fabaoDTO);

			fabao.setId(fabao.uuid());

			fabaoMapper.insert(fabao);
		}
	}

	@Override
	public void deleteById(String id) {
		fabaoMapper.deleteById(id);
	}

	@Override
	public void updateById(FabaoDTO fabaoDTO) {
		if (StringUtils.isEmpty(fabaoDTO.getId())) {
			throw new GlobalException(ResponseCode.BAD_REQUEST, CustomMessages.ID_NOT_NULL);
		}

		boolean result = validataDuplicate(fabaoDTO);

		if (result) {
			Fabao fabao = toEntity(fabaoDTO);

			fabaoMapper.updateById(fabao);
		}
	}

	@Override
	public Page<Fabao> selectByPage(FabaoPager pager) {
		QueryWrapper<Fabao> queryWrapper = new QueryWrapper<>();
		Page<Fabao> page = Pager.ofPage(pager);

		queryWrapper.eq(
				pager.getCategoryId() != null,
				"category_id", pager.getCategoryId()
		);
		queryWrapper.eq(
				StringUtils.isNotEmpty(pager.getRoleId()),
				"role_id", pager.getRoleId()
		);

		return fabaoMapper.selectPage(page, queryWrapper);
	}

	/**
	 * 验证角色法宝是否重复
	 * @param fabaoDTO 法宝信息
	 * @return 角色拥有此法宝时抛出异常，否则返回true
	 */
	private boolean validataDuplicate(FabaoDTO fabaoDTO) {
		String fabaoId = fabaoDTO.getId();

		QueryWrapper<Fabao> queryWrapper = new QueryWrapper<>();

		queryWrapper.eq("role_id", fabaoDTO.getRoleId());
		queryWrapper.eq("category_id", fabaoDTO.getCategoryId());
		queryWrapper.ne(StringUtils.isNotEmpty(fabaoId), "id", fabaoId);

		Long count = fabaoMapper.selectCount(queryWrapper);

		if (count > 0) {
			throw new GlobalException(ResponseCode.CONFLICT, "角色已经拥有此法宝。");
		}

		return true;
	}

	private Fabao toEntity(FabaoDTO fabaoDTO) {
		Fabao fabao = new Fabao();

		fabao.setId(fabaoDTO.getId());
		fabao.setScore(0);
		fabao.setGrade(fabaoDTO.getGrade());
		fabao.setRoleId(fabaoDTO.getRoleId());
		fabao.setCategoryId(fabaoDTO.getCategoryId());
		fabao.setWearStatus(fabaoDTO.getWearStatus());

		return fabao;
	}

}